/**
 * 测试报告信息路由
 *
 */
const fs = require('fs-extra');
const path = require('path');
// const multer = require('multer');
const middleware = require('./../middleware');
const PhoenixError = require('./../../models/phoenix-error');

const report = require('./../../models/export/report');
// const cacheUtil = require('../../cacheUtil');
const ProgressIndicator = require('../../models/progress-indicator');
const utility = require('../../models/utility');
const { eventHub } = require('../../models/event-hub');

/**
 * 获取测试报告（docx）
 * @param req
 * @param res
 * @param next
 * @returns {Promise}
 */
function getReport(req, res, next) {
  const { projectVersionId } = req.params;
  const { format, complete, reportType } = req.query;
  const { $projectVersion, $project, $me } = req;
  const versionReport = report.getReport(
    projectVersionId,
    req.$locale,
    $projectVersion,
    $project,
    $me,
    format,
    Boolean(parseInt(complete, 10)),
    reportType,
    req.$license,
  );
  const progressIndicator = new ProgressIndicator();
  const chan = utility.getSessionId();
  progressIndicator.on('progress', (progress) => {
    if (chan) {
      eventHub.emit(chan, 'generate', progress);
    }
  });
  versionReport.generate(progressIndicator)
    .then(({ reportPath, cachePath }) => {
      res.setHeader('Access-Control-Expose-Headers', 'Content-Disposition');
      res.download(reportPath, encodeURI(path.basename(reportPath)), () => fs.remove(cachePath));
    })
    .catch((err) => {
      next(new PhoenixError(err));
    });
}

/**
 * 获取测试报告概要信息（json）
 * @param req
 * @param res
 * @param next
 * @returns {Promise}
 */
function getSummary(req, res, next) {
  const report = require('./../../models/report');
  const { projectVersionId } = req.params;
  report.getSummary(projectVersionId, req.$projectVersion, req.$project, req.$me)
    .then((summary) => {
      res.json(summary);
    })
    .catch((err) => {
      next(new PhoenixError(err));
    });
}

function getStaticAnalyzeReport(req, res, next) {
  const { projectVersionId } = req.params;
  const { $projectVersion, $project, $me } = req;
  const {
    format,
    reportType,
    reportCategory,
  } = req.query;
  let {
    levels,
    ruleSets,
    defectStatus,
  } = req.query;
  levels = levels ? [].concat(levels).map((level) => parseInt(level, 10)) : undefined;
  defectStatus = defectStatus ? [].concat(defectStatus).map((status) => parseInt(status, 10)) : undefined;
  ruleSets = ruleSets ? [].concat(ruleSets) : undefined;
  const versionReport = report.getStaticAnalyzeReport(
    projectVersionId,
    req.$locale,
    $projectVersion,
    $project,
    $me,
    format,
    {
      levels,
      ruleSets,
      defectStatus,
    },
    reportType,
    reportCategory,
    req.$license,
  );
  const progressIndicator = new ProgressIndicator();
  const chan = utility.getSessionId();
  progressIndicator.on('progress', (progress) => {
    if (chan) {
      eventHub.emit(chan, 'generate', progress);
    }
  });
  versionReport.generate(progressIndicator)
    .then(({ reportPath, cachePath }) => {
      res.setHeader('Access-Control-Expose-Headers', 'Content-Disposition');
      res.download(reportPath, encodeURI(path.basename(reportPath)), () => fs.remove(cachePath));
    })
    .catch((err) => {
      next(new PhoenixError(err));
    });
}

function generateCodeInstrumentationReport(req, res, next) {
  const { format, complete, includeTestcase } = req.query;
  const { $projectVersion, $project, $me } = req;
  report.getCodeInstrumentationReport(
    req.body,
    req.$locale,
    $projectVersion,
    $project,
    $me,
    format,
    !!parseInt(complete, 10),
    !!parseInt(includeTestcase, 10)
  )
    .then((versionReport) => versionReport.generate())
    .then(({ reportPath, cachePath }) => {
      res.setHeader('Access-Control-Expose-Headers', 'Content-Disposition');
      res.download(reportPath, encodeURI(path.basename(reportPath)), () => fs.remove(cachePath));
    })
    .catch((err) => {
      next(new PhoenixError(err));
    });
}

/**
 * Export model definition object.
 */
module.exports = (app, prefix) => {
  const reportURL = `${prefix}/project-versions/:projectVersionId/report`;
  const reportSummaryURL = `${prefix}/project-versions/:projectVersionId/summary.json`;
  const staticAnalyzeURL = `${prefix}/project-versions/:projectVersionId/static-analyze/report`;
  const codeInstrumentationReportGenURL = `${prefix}/project-versions/:projectVersionId/code-instrumentation-results/reports`;

  app.get(reportURL, middleware.user.requireTokenUnexpired);
  app.get(reportURL, middleware.user.requireAvailable);
  app.get(reportURL, middleware.user.requireTester);
  app.get(reportURL, middleware.projectVersion.requireProjectVersionExist);
  app.get(reportURL, middleware.project.requireProjectAccess);
  app.get(reportURL, middleware.license.requireLicenseExist);
  app.get(reportURL, middleware.progressNotify([{ name: 'generate', scale: 1 }]));
  app.get(reportURL, getReport);

  app.get(reportSummaryURL, middleware.user.requireTokenUnexpired);
  app.get(reportSummaryURL, middleware.user.requireAvailable);
  app.get(reportSummaryURL, middleware.user.requireTester);
  app.get(reportSummaryURL, middleware.projectVersion.requireProjectVersionExist);
  app.get(reportSummaryURL, middleware.project.requireProjectAccess);
  app.get(reportSummaryURL, getSummary);

  app.get(staticAnalyzeURL, middleware.user.requireTokenUnexpired);
  app.get(staticAnalyzeURL, middleware.user.requireAvailable);
  app.get(staticAnalyzeURL, middleware.user.requireTester);
  app.get(staticAnalyzeURL, middleware.projectVersion.requireProjectVersionExist);
  app.get(staticAnalyzeURL, middleware.project.requireProjectAccess);
  app.get(staticAnalyzeURL, middleware.license.requireLicenseExist);
  app.get(staticAnalyzeURL, middleware.progressNotify([{ name: 'generate', scale: 1 }]));
  app.get(staticAnalyzeURL, getStaticAnalyzeReport);

  // 创建代码插桩报告
  app.put(codeInstrumentationReportGenURL, middleware.user.requireTokenUnexpired);
  app.put(codeInstrumentationReportGenURL, middleware.user.requireAvailable);
  app.put(codeInstrumentationReportGenURL, middleware.user.requireTester);
  app.put(codeInstrumentationReportGenURL, middleware.projectVersion.requireProjectVersionExist);
  app.put(codeInstrumentationReportGenURL, middleware.project.requireProjectAccess);
  app.put(codeInstrumentationReportGenURL, generateCodeInstrumentationReport);
};
